Ensure drawing context is set
authorEmmanuele Bassi <ebassi@gnome.org>
Thu, 15 Sep 2016 09:05:05 +0000 (10:05 +0100)
committerEmmanuele Bassi <ebassi@gnome.org>
Thu, 15 Sep 2016 09:17:24 +0000 (10:17 +0100)
If somebody decides to use gtk_widget_set_double_buffered() in the
middle of a draw() then there's the risk of calling end_draw_frame()
with an invalid pointer.

Some overeager compilers may warn about the double_buffered bit field
changing values and leading to a potentially uninitialized variable.

In order to avoid compiler warnings or crashes, we can simply store the
value of the double_buffered bit field at the beginning of the rendering
and use that instead of the actual bit field.

https://bugzilla.gnome.org/show_bug.cgi?id=771463

gtk/gtkwidget.c

index 017bbbed53c6ffee54f2b20b93b111a2df5f6f0f..3f48b14337dedc21d88af828179a09593577184c 100644 (file)
@@ -17464,8 +17464,14 @@ gtk_widget_render (GtkWidget            *widget,
   gboolean do_clip;
   cairo_t *cr;
   int x, y;
+  gboolean is_double_buffered;
 
-  if (priv->double_buffered)
+  /* We take the value here, in case somebody manages to changes
+   * the double_buffered value inside a ::draw call, and ends up
+   * breaking everything.
+   */
+  is_double_buffered = priv->double_buffered;
+  if (is_double_buffered)
     {
       /* We only render double buffered on native windows */
       if (!gdk_window_has_native (window))
@@ -17492,7 +17498,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
 
   gtk_widget_draw_internal (widget, cr, do_clip);
 
-  if (priv->double_buffered)
+  if (is_double_buffered)
     gdk_window_end_draw_frame (window, context);
   else
     cairo_destroy (cr);